﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace ASTBuilder
{
    public partial class MainForm : Form
    {
        //environment properties fields
        private bool isSaved;
        private bool fileIsCreated;
        private bool tokenListCreated;
        private bool parseTreeCreated;
        private String currentDir;
        private String currentFileName;
        private String fullCurrentPath;
        private String tempFileNamePath;
        private FileStream outFile;
        private FileStream inFile;
        private StreamWriter outStream;
        private Stream someStr;
        private StreamReader inStream;

        //functionality fields
        private Interpreter interpreter;
        private ParseTree tree;

        //File
        //New
        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (isSaved)
            {
                textBoxMain.Clear();
                currentFileName = "Untitled";
                base.ResetText();
                base.Text = "Interpreter: " + currentFileName;
            }
            else
            {
                DialogResult result =
                MessageBox.Show("File is not saved! Are you sure you want to create a new file", 
                                        "Attention: File not saved!", MessageBoxButtons.OKCancel);
                if (result == DialogResult.OK)
                {
                    textBoxMain.Clear();
                    currentFileName = "Untitled";
                    base.ResetText();
                    base.Text = "Interpreter: " + currentFileName;
                }
            }
        }
        //Open
        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFile = new OpenFileDialog();
            openFile.Title = "Open File";
            openFile.InitialDirectory = currentDir;

            try
            {
                if (openFile.ShowDialog() == DialogResult.OK)
                {
                    currentFileName = openFile.FileName;                    
                    fullCurrentPath = currentFileName;
                    
                    try
                    {
                        inFile = File.Open(currentFileName, FileMode.Open,
                                                            FileAccess.ReadWrite);
                        inStream = new StreamReader(inFile);
                        textBoxMain.Text = inStream.ReadToEnd();

                        base.ResetText();
                        base.Text = "Interpreter: " + currentFileName;
                        this.isSaved = true;
                        this.fileIsCreated = true;
                        this.textBoxOutput.ResetText();

                        inStream.Close();
                        openFile.Dispose();
                    }
                    catch (Exception exc)
                    {
                        textBoxOutput.Text = exc.ToString();
                    }
                }
            }
            catch (Exception exc)
            {
                textBoxOutput.Text = exc.ToString();
            }
        }
        //Save
        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!this.fileIsCreated)
            {
                this.saveAsToolStripMenuItem_Click(sender, e);
            }
            else
            {
                if (!this.isSaved)
                {
                    try
                    {
                        //outFile = File.Open(currentFileName, FileMode.CreateNew,FileAccess.Write);
                        File.WriteAllText(fullCurrentPath, textBoxMain.Text);
                        //outStream = new StreamWriter(fullCurrentPath, true);
                        base.ResetText();
                        base.Text = "Interpreter: " + currentFileName;
                        this.isSaved = true;
                        this.fileIsCreated = true;

                        textBoxOutput.ResetText();
                        textBoxOutput.Text = "File is saved.";

                        outStream.Close();
                    }
                    catch (Exception exc)
                    {
                        textBoxOutput.Text = exc.ToString();
                    }
                }
            }
        }
        //Save As...
        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
            SaveFileDialog saveFileAs = new SaveFileDialog();
            saveFileAs.Title = "Save As...";
            saveFileAs.DefaultExt = "txt";
            saveFileAs.AddExtension = true;
            saveFileAs.InitialDirectory = currentDir;

            
                if (saveFileAs.ShowDialog() == DialogResult.OK)
                {
                    currentFileName = saveFileAs.FileName;
                    FileInfo fi = new FileInfo(currentFileName);
                    currentDir = fi.DirectoryName;
                    fullCurrentPath = currentFileName;
                    File.WriteAllText(fullCurrentPath, textBoxMain.Text);
                    //try
                    //{
                        //outFile = File.Open(currentFileName, FileMode.CreateNew,FileAccess.Write);
                        //outStream = new StreamWriter(outFile);
                        //outStream.Write(textBoxMain.Text);

                        base.ResetText();
                        base.Text = "Interpreter: " + currentFileName;
                        this.isSaved = true;
                        this.fileIsCreated = true;

                        //outStream.Close();
                        saveFileAs.Dispose();
                    //}
                }
            }
            catch (Exception exc)
            {
                textBoxOutput.Text = exc.ToString();
            }   
        }
        //Exit
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            outStream.Dispose();
            if (isSaved)
            {
                try
                {
                    // Delete the temp file (if it exists)
                    if (File.Exists(tempFileNamePath))
                    {
                        File.Delete(tempFileNamePath);
                        textBoxOutput.ResetText();
                        textBoxOutput.Text = "Deleted temp file";
                        this.Close();
                    }
                }
                catch (Exception ex)
                {
                    textBoxErrors.ResetText();
                    textBoxErrors.Text = "Temp file not deleted: " + ex.ToString();
                }
                
            }
            else
            {
                DialogResult result = MessageBox.Show(
                    "The file is not saved. Are you sure you want to exit?",
                    "Warning", MessageBoxButtons.YesNo);
                if (result == DialogResult.Yes)
                {
                    try
                    {
                        // Delete the temp file (if it exists)
                        if (File.Exists(tempFileNamePath))
                        {
                            File.Delete(tempFileNamePath);
                            textBoxOutput.ResetText();
                            textBoxOutput.Text = "Deleted temp file";
                            this.Close();// :)
                        }
                    }
                    catch (Exception ex)
                    {
                        textBoxErrors.ResetText();
                        textBoxErrors.Text = "Temp file not deleted: " + ex.ToString();
                    }
                }
            }
        }
        //Interpret
        //Read Tokens
        private void readTokensToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!isSaved)
            {
                textBoxErrors.ResetText();
                textBoxErrors.Text = "File is not saved";
            }
            else
            {
                try
                {
                    
                    //outStream = File.CreateText(tempFileNamePath);
                    interpreter.resetLexer(this.textBoxMain.Text, outStream);
                    interpreter.getAllTokens();
                    //interpreter.printTokenList();
                    textBoxOutput.ResetText();
                    //String output = File.ReadAllText(tempFileNamePath);
                    textBoxOutput.Text = "Token list created successfuly";// + "\n" + output;
                    tokenListCreated = true;
                    //outStream.Dispose();
                }
                catch (Exception ex)
                {
                    textBoxErrors.ResetText();
                    textBoxErrors.Text = "Error: " + ex.ToString();
                }
            }
        }
        //Build AST
        private void buildASTToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!isSaved)
            {
                textBoxErrors.ResetText();
                textBoxErrors.Text = "File is not saved";
            }
            else
            {
                if (!tokenListCreated)
                {
                    textBoxErrors.ResetText();
                    textBoxErrors.Text = "Token list is not created";
                }
                else
                {
                    try
                    {
                        interpreter.getLookAhead();
                        tree = new ParseTree(null, null);
                        tree = interpreter.getParseTree();
                        interpreter.resetParser();
                        //tree.printTree(tree.getRoot(), outStream);
                        textBoxOutput.ResetText();
                        //String output = File.ReadAllText(tempFileNamePath);
                        textBoxOutput.Text = "Parse tree generated \n";// + output;
                        parseTreeCreated = true;
                    }
                    catch (Exception ex)
                    {
                        textBoxErrors.ResetText();
                        textBoxErrors.Text = "Error" + ex.ToString();
                    }
                }
            }
        }
        //Parse AST
        private void parseASTToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!isSaved)
            {
                textBoxErrors.ResetText();
                textBoxErrors.Text = "File is not saved";
            }
            else
            {
                if (!parseTreeCreated)
                {
                    textBoxErrors.ResetText();
                    textBoxErrors.Text = "Parse tree is not created";
                }
                else
                {
                    try
                    {
                        //outStream.Dispose();
                        //outStream = File.CreateText(tempFileNamePath);
                        interpreter.runParseTree(tree.getRoot(), outStream);
                        textBoxOutput.ResetText();
                        String output = File.ReadAllText(tempFileNamePath);
                        //textBoxOutput.Text = "Program run successfuly";
                        textBoxOutput.AppendText(output);
                    }
                    catch (Exception ex)
                    {
                        textBoxErrors.ResetText();
                        textBoxErrors.Text = "Error" + ex.ToString();
                    }
                }
            }
        }
        //Reset
        private void resetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
            outStream = File.CreateText(tempFileNamePath);
            interpreter.resetLexer(this.textBoxMain.Text, outStream);
            interpreter.resetParser();
            textBoxOutput.ResetText();
            textBoxOutput.Text = "Interpreter reset";
            }
            catch(Exception ex)
            {
                textBoxErrors.ResetText();
                textBoxErrors.Text = ex.ToString();
            }
        }
        //Help
        //About
        private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("An Interpreter for a custom,\n" +
                            "C-like language\n" +
                            "(c) Stefan Bojarovski, 2010");
        }
        private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }
        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            this.isSaved = false;
            this.textBoxOutput.Text = "Attention: file is not saved";
        }

        public MainForm()
        {
            //set the environment for a fresh start
            this.isSaved = false;
            this.fileIsCreated = false;
            currentDir = Environment.GetFolderPath(
                                        Environment.SpecialFolder.MyDocuments);
            currentDir += @"\Interpreter";
            currentFileName = "Untitled";

            Directory.CreateDirectory(currentDir);

            tempFileNamePath = Path.GetTempFileName();
            Console.WriteLine(tempFileNamePath);
            outStream = File.CreateText(tempFileNamePath);
            this.interpreter = new Interpreter("", outStream);
            tokenListCreated = false;
            parseTreeCreated = false;
            //fullCurrentPath = tempFileName;

            InitializeComponent();
        }
        protected override void OnLoad(EventArgs e)
        {
            this.Text += ": " + currentFileName;
            base.OnLoad(e);
        }
        [STAThread]
        public static void Main()
        {
            Application.Run(new MainForm());
        }

        
    }
}
